package com.coder520.sync_learning.demo;

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class BoundQueue<T> {

	private Object[] objects;
	//添加的下标，删除的下标和数组的当前数量
	private int addIndex,removeIndex,count;
	private Lock lock=new ReentrantLock();
	
	private Condition notEmpty=	lock.newCondition();
	private Condition notFull=lock.newCondition();
	
	public BoundQueue(int size) {
		// TODO Auto-generated constructor stub
		objects=new Object[size];
	}
	
	/**
	 * 添加一个数组，当数组满了之后，则添加线程进入等待状态，知道有空位
	 * 
	 *	2018年6月13日
	 * @throws InterruptedException 
	 */
	public  void add(T t) throws InterruptedException {
		// TODO Auto-generated method stub
		lock.lock();
		try {
			while (count==objects.length) 
				notFull.await();
				objects[addIndex]=t;
				if (++addIndex==objects.length)
					addIndex=0;
				++count;
				notEmpty.signal();
		} finally {
			// TODO: handle finally clause
			lock.unlock();
		}
	}
	
	/**
	 * 由头部删除一个元素，如果数组为空，则删除线程进入等待状态，直到有新的元素添加进来
	 * @return
	 *	2018年6月13日
	 * @throws InterruptedException 
	 */
	@SuppressWarnings("unchecked")
	public T remove() throws InterruptedException {
		// TODO Auto-generated method stub
		lock.lock();
		try {
			while(count==0)
				notEmpty.await();
			Object xObject=objects[removeIndex];
			if (++removeIndex==objects.length) {
				removeIndex=0;
			}
			--count;
			notFull.signal();
			return (T)xObject;
		} finally {
			// TODO: handle finally clause
			lock.unlock();
		}
	}
	
}
